﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Xml.Linq;
using AvalonDock;
using System.Collections.ObjectModel;
using RiskMan.DataClass;
using RiskMan.Config;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Windows.Media;
using RiskMan.Views.AboutFrom;
using RiskMan.Views.Dialogs;
using RiskMan.Views.Robot;
using RiskMan.Views.Table;
using History = RiskMan.Config.History;


namespace RiskMan
{
    delegate void NewDataHandler(string data);
    public partial class MainWindow : Window
    {
        public static MainWindow StaticLevel;

        //private Register reg;

        public ObservableCollection<DocumentContent> MyDocuments { get; private set; }
        public Data _dataProvider;
        public String path = "";
        List<string> listWindow = new List<string>();

        public static string Password;
        public static string Login;

        public string AppDir; // путь к папке приложения
        public static bool BConnecting; // флаг процесса подключения к серверу
        public static bool BDisconnecting; // флаг процесса отключения от сервера
        public static bool BConnected; // флаг наличия подключения к серверу

        public static TXmlConnector OConn; // коннектор

        private event NewDataHandler OnNewDataEvent;

        public static bool LogFlag = true; // флаг записи лог-файла
        public static StreamWriter LogFile; // переменная лог-файла
        public char PointChar; // символ для замены точки в числах
        public static List<string> ColInstrumentSubscribe; //коллекция инструментов, на которые подписаны
        public static ObservableCollection<HistoryItems> DictionaryHistoryData; // словарь по истории получаемых данных (период/ бумага)
        public static List<int> TicksListInstruments; //Лист инструментов необходимых для получении истории

        History history;
        private DispatcherTimer timer;
        public ShowMassege Method;


        public DateTime startNight = new DateTime();
        public DateTime endNight = new DateTime();

        public MainWindow()
        {
            StaticLevel = this;
            try
            {
                // определение папки, в которой запущена программа
                string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) + "\\SystemGetchik\\";
                AppDir = path;
                ColInstrumentSubscribe = new List<string>();
                DictionaryHistoryData = new ObservableCollection<HistoryItems>();
                TicksListInstruments = new List<int>();

                InitializeComponent();


                MyDocuments = new ObservableCollection<DocumentContent>();
                DataContext = this;

                _dataProvider = new Data();

                if (LogFlag)
                {
                    if (!Directory.Exists(path))
                    {
                        System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(path);
                        dir.Create();
                    }
                    path = AppDir + "log.txt";
                    if (File.Exists(path)) File.Delete(path);
                    File.Create(path).Close();
                    LogFile = File.AppendText(path);
                    WriteLog("START LOGGING");
                }

                DictionaryMarkets = new Dictionary<int, string>();
                DictionaryTimeFrame = new Dictionary<int, string>();

                OConn = new TXmlConnector();

                string logPath = AppDir + "\0";
                string resStr = OConn.ConnectorInitialize(logPath, 3);

                OConn.NewData += new EventHandler<TXmlConnector.NewDataEventArgs>(OnNewDataConnector);

                this.OnNewDataEvent += new NewDataHandler(OnNewData);
                history = new History(_dataProvider);
                history.Load();


                #region загрузка вермени и тп
                try
                {
                    DateTime startD = Properties.Settings.Default.StartDay;
                    DateTime endD = Properties.Settings.Default.EndDay;

                    DateTime startN = Properties.Settings.Default.StartNight;
                    DateTime endN = Properties.Settings.Default.EndNight;

                    Properties.Settings.Default.StartDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, startD.Hour, startD.Minute, 0);
                    Properties.Settings.Default.EndDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, endD.Hour, endD.Minute, 0);

                    Properties.Settings.Default.StartNight = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, startN.Hour, startN.Minute, 0);
                    Properties.Settings.Default.EndNight = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, endN.Hour, endN.Minute, 0);

                    this.startNight = Properties.Settings.Default.StartNight;
                    this.endNight = Properties.Settings.Default.EndNight;
                }
                catch (Exception)
                {
                    new DialogOkCancel("При инициализации произоша ошибка", "Ошибка");
                }
                #endregion
                Method = RobotLog;
            }
            catch (Exception ex)
            {
                new DialogOkCancel("При инициализации произоша ошибка: " + ex.Source, "Ошибка");
            }
            
        }

        private void OnNewData(string data)
        {
            Transaq_HandleData(data);
        }
        private void OnNewDataConnector(object sender, TXmlConnector.NewDataEventArgs e)
        {
            //Этот метод вызывается при получении новых данных
            //this.onNewDataEvent += new NewDataHandler(OnNewData)
            this.Dispatcher.Invoke(OnNewDataEvent, new object[] { e.data }); //чтобы не было проблем с отображением
        }
        void Transaq_Disconnect()
        {
            // отключение коннектора от сервера Транзак
            BConnected = false;
            BConnecting = false;
            BDisconnecting = true;

            Transaq_Reflect();
            string cmd = _dataProvider.TransaqCommand.Disconnect();

            WriteLog("SendCommand: " + cmd);
            string res = OConn.SendCommand(cmd);
            WriteLog("ServerReply: " + res);

            Transaq_Reflect();
        }

        public void RobotLog(string str)
        {
            for (int i = 0; i < dockManager.Documents.Count; i++)
            {

                if (dockManager.Documents[i].Title == Cfg.MainLogRobot)
                {
                    LogRobot.Instance.Log(str);
                    Cfg.SetLog(str);
                }
            }

        }


        public static void WriteLog(string logStr)
        {
            if (LogFlag)
            {
                LogFile.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + " " + logStr);
                LogFile.Flush();
            }
        }
        public void ShowStatus(string statusStr)
        {
            // вывод сообщения в строке статуса формы
            txt_Status.Text = statusStr;
        }

        void Transaq_Connect()
        {
            // подключение коннектора к серверу Транзак
            BConnected = false;
            BConnecting = true;
            BDisconnecting = false;

            if (String.IsNullOrEmpty((Password)))
                Password = "n5GN3s";
            if (String.IsNullOrEmpty((Login)))
                Login = "TCNN9966";

            // проверка наличия параметров
            if (String.IsNullOrEmpty(Login))
            {
                ShowStatus("Не указан логин");
                return;
            }
            if (String.IsNullOrEmpty(Password))
            {
                ShowStatus("Не указан пароль");
                return;
            }
            if (String.IsNullOrEmpty(Properties.Settings.Default.IPadress))
            {
                ShowStatus("Не указан IP-адрес");
                return;
            }
            if (String.IsNullOrEmpty(Properties.Settings.Default.Port))
            {
                ShowStatus("Не указан порт");
                return;
            }

            Transaq_Reflect();


            // формирование текста команды
            string cmd = "<command id=\"connect\">";
            cmd = cmd + "<login>" + Login + "</login>";
            cmd = cmd + "<password>" + Password + "</password>";
            cmd = cmd + "<host>" + Properties.Settings.Default.IPadress + "</host>";
            cmd = cmd + "<port>" + Properties.Settings.Default.Port + "</port>";
            cmd = cmd + "<logsdir>" + AppDir + "</logsdir>";
            cmd = cmd + "<micex_registers>true</micex_registers>";
            cmd += "<rqdelay>330</rqdelay>";
            cmd = cmd + "</command>";

            // отправка команды
            WriteLog("SendCommand: <command id=\"connect\"><login>" + Login + "</login><password>*</password><host>" + Properties.Settings.Default.IPadress + "</host><port>" + Properties.Settings.Default.Port + "</port><logsdir>" + AppDir + "</logsdir><rqdelay>330</rqdelay></command>");
            string res = OConn.SendCommand(cmd);
            WriteLog("ServerReply: " + res);

            Transaq_Reflect();
        }

        void Transaq_Reflect()
        {
            // отображение состояния подключения на форме
            string status = "offline";
            string button = "Подключить";
            btnConnect.IsEnabled = true;
            btnDisconnect.IsEnabled = false;
            MenuItem_RunConnect.IsEnabled = true;
            MenuItem_RunDisconnect.IsEnabled = false;
            string msg = "";

            if (BConnected)
            {
                status = "online";
                btnConnect.IsEnabled = false;
                btnDisconnect.IsEnabled = true;
                MenuItem_RunConnect.IsEnabled = false;
                MenuItem_RunDisconnect.IsEnabled = true;
                MainWindow.StaticLevel._dataProvider.GetStopOrderListAllforInstrunemts();
                MainWindow.StaticLevel._dataProvider.GetOrderListAllforInstrunemts();

            }
            else
            {
                if (BConnecting)
                {
                    status = "connect";
                    button = "Подключаю";
                    msg = "Подключение к серверу...";
                }
                if (BDisconnecting)
                {
                    status = "disconn";
                    button = "Отключаю";
                    msg = "Отключение от сервера...";
                }
            }


            if (msg.Length > 0) ShowStatus(msg);
        }

        public void dockManager_Loaded(object sender, RoutedEventArgs args)
        {

        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //string uid = Cfg.GetID() + Cfg.GetMacAddress();
            //reg = new Register(uid);

            dockManager.Loaded += new RoutedEventHandler(dockManager_Loaded);


            listWindow = GetWindow();
            foreach (var item in listWindow)
            {
                PublishNewDocument(item);
            }
        }

        private List<string> GetWindow()
        {
            return (List<string>)XmlHistory.GetXmlData(XmlHistory.FilenameWindow);
        }

        private void CreateNewDocument(object sender, RoutedEventArgs e)
        {
            string baseDocTitle = ((MenuItem)sender).Header.ToString();
            for (int i = 0; i < dockManager.Documents.Count; i++)
            {
                if (dockManager.Documents[i].Title == baseDocTitle)
                {
                    dockManager.Documents[i].Activate();
                    return;
                }
            }
            PublishNewDocument(baseDocTitle);

        }

        private void PublishNewDocument(string baseDocTitle)
        {

            if (baseDocTitle == Cfg.MainTableOrder)
            {
                TableOrder st = new TableOrder() { Name = "TableDeals", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }
            if (baseDocTitle == Cfg.MainTableDeal)
            {
                TableDeal st = new TableDeal() { Name = "TableOrders", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }
            if (baseDocTitle == Cfg.MainTableStopOrder)
            {
                TableStopOrders st = new TableStopOrders() { Name = "TableStops", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }
            if (baseDocTitle == Cfg.MainTablePositionMMVB)
            {
                TablePositionMMVB st = new TablePositionMMVB { Name = "TablePositionMMVB", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }
            if (baseDocTitle == Cfg.MainTableTtp)
            {
                TableTTP st = new TableTTP { Name = "TableTTP", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }

            if (baseDocTitle == Cfg.MainTableHistory)
            {
                HistoryCandle st = new HistoryCandle { Name = "History", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }

            if (baseDocTitle == Cfg.MainfunctionRobot)
            {
                RobotView st = new RobotView { Name = "Robot", Title = baseDocTitle, Background = new SolidColorBrush(new Color() { R = 145, G = 158, B = 167 }) };
                MyDocuments.Add(st);
                st.Activate();
            }

            if (baseDocTitle == Cfg.MainLogRobot)
            {
                LogRobot st = LogRobot.Instance;
                st.Name = "LogRobot";
                st.Title = baseDocTitle;
                st.Background = new SolidColorBrush(new Color() {R = 145, G = 158, B = 167});
                MyDocuments.Add(st);
                st.Activate();
  
            }

            if (baseDocTitle == Cfg.MainLogSovetnik)
            {

                SovetnikLog st = SovetnikLog.Instance;
                st.Name = "LogSovetnik";
                st.Title = baseDocTitle;
                st.Background = new SolidColorBrush(new Color() {R = 145, G = 158, B = 167});
                MyDocuments.Add(st);
                st.Activate();
            }
        }

        private void ClearDocumentsList(object sender, RoutedEventArgs e)
        {
            MyDocuments.Clear();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            listWindow.Clear();
            foreach (var item in MyDocuments)
            {
                listWindow.Add(item.Title);
            }
            SetWindow(listWindow);

            {
                if ((new DialogYesNo("Вы действительно хотите выйти?", "Внимание!")).Result == MessageBoxResult.Yes)
                {
                    if ((new DialogYesNo("Сохранить данные?", "Внимание!")).Result == MessageBoxResult.Yes)
                    {
                        history.Save();
                    }
                    TrayIcon.Visible = false;
                }
                else
                    e.Cancel = true;
            }



        }

        private void SetWindow(List<string> list)
        {
            XmlHistory.SetXmlData(XmlHistory.FilenameWindow, (Object)(list));
        }

        private void Button1_Click_1(object sender, RoutedEventArgs e)
        {
            if (this.Topmost == false)
            {
                this.Topmost = true;
                Button1.Style = (Style)this.Resources["TopMost_ButtonStyle"];
                Cfg.SetLog(this.GetType().FullName + "." + MethodBase.GetCurrentMethod().Name + ": Свойсвтво окна \"по верх всех\" - поставлено", MainWindow.StaticLevel.LsbxAnswer, GetType(), MethodBase.GetCurrentMethod());
            }
            else
            {
                this.Topmost = false;
                Button1.Style = (Style)this.Resources["TopMostOut_ButtonStyle"];
                Cfg.SetLog(this.GetType().FullName + "." + MethodBase.GetCurrentMethod().Name + ": Свойсвтво окна \"по верх всех\" - снято", LsbxAnswer, GetType(), MethodBase.GetCurrentMethod());
            }
        }



        /// <summary>
        /// создание транзакционного соединия 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void button2_Click(object sender, RoutedEventArgs e)
        {
            Connecting();
        }

        private void Connecting()
        {
            Connect connect = new Connect();
            connect.ShowDialog();


            // нажата кнопка подключения
            if (connect.DialogResult == true)
                if (BConnected || BConnecting)
                {
                    Transaq_Disconnect();
                }
                else
                {
                    if (!BConnecting) Transaq_Connect();
                }
        }

        #region icon to tray

        private System.Windows.Forms.NotifyIcon TrayIcon = null;
        private ContextMenu TrayMenu = null;
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            createTrayIcon();
        }


        private bool createTrayIcon()
        {
            bool result = false;

            if (TrayIcon == null)
            {
                TrayIcon = new System.Windows.Forms.NotifyIcon();
                TrayIcon.Icon = RiskMan.Properties.Resources.linechart_8075;
                TrayIcon.Text = "Робот по системе Герчика";

                TrayMenu = Grid_Temp.Resources["TrayMenu"] as ContextMenu;

                TrayIcon.Click += delegate(object sender, EventArgs e)
                {
                    if ((e as System.Windows.Forms.MouseEventArgs).Button == System.Windows.Forms.MouseButtons.Left)
                    {
                        ShowHideMainWindow(sender, null);
                    }
                    else
                    {
                        TrayMenu.IsOpen = true;
                        Activate();
                    }
                };
                result = true;
            }
            else
            {
                result = true;
            }

            TrayIcon.Visible = true;
            return result;
        }

        private void ShowHideMainWindow(object sender, RoutedEventArgs e)
        {
            TrayMenu.IsOpen = false; // спрячем менюшку, если она вдруг видима
            if (IsVisible)
            {
                Hide();
                (TrayMenu.Items[0] as MenuItem).Header = "Показать";
            }
            else
            {
                Show();
                (TrayMenu.Items[0] as MenuItem).Header = "Скрыть";
                WindowState = CurrentWindowState;
                Activate();
            }
        }

        private WindowState fCurrentWindowState = WindowState.Normal;
        public WindowState CurrentWindowState
        {
            get { return fCurrentWindowState; }
            set { fCurrentWindowState = value; }
        }

        protected override void OnStateChanged(EventArgs e)
        {
            base.OnStateChanged(e);
            if (this.WindowState == System.Windows.WindowState.Minimized)
            {
                //Hide( );
                (TrayMenu.Items[0] as MenuItem).Header = "Показать";
            }
            else
            {
                CurrentWindowState = WindowState;
            }
        }





        private bool fCanClose;
        public bool CanClose
        {
            get { return fCanClose; }
            set { fCanClose = value; }
        }

        protected void Window_Closing(System.ComponentModel.CancelEventArgs e)
        {

            {
                if ((new DialogYesNo("Вы действительно хотите выйти?", "Внимание!")).Result == MessageBoxResult.Yes)
                {
                    if ((new DialogYesNo("Сохранить данные?", "Внимание!")).Result == MessageBoxResult.Yes)
                    {
                        history.Save();
                    }
                    TrayIcon.Visible = false;
                }
                else
                    e.Cancel = true;
            }
        }



        private void MenuExitClick(object sender, RoutedEventArgs e)
        {
            if ((new DialogYesNo("Вы действительно хотите выйти?", "Внимание!")).Result == MessageBoxResult.Yes)
            {
                if ((new DialogYesNo("Сохранить данные?", "Внимание!")).Result == MessageBoxResult.Yes)
                {
                    history.Save();
                }
            }
            else
                return;

            TrayIcon.Visible = false;
            Environment.Exit(9);
            //  Close( );
        }

        #endregion

        private void MenuItem_SaveSettings_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                history.Save();
            }
            catch (Exception ex)
            {
                new DialogOkCancel(ex.ToString(), "MenuItem_SaveSettings_Click");
            }
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        /// <summary>
        /// About form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Click_2(object sender, RoutedEventArgs e)
        {
            About about = new About();
            about.ShowDialog();
        }

        private void MenuItem_LogFolder_Click(object sender, RoutedEventArgs e)
        {
            String path = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) + "\\SystemGetchik\\";
            if (Directory.Exists(path))
                Process.Start("explorer", path);
        }


        private void BtnDisconnect_OnClick(object sender, RoutedEventArgs e)
        {
            Disconnect();
        }
        private void Disconnect()
        {
            if (BConnected || BConnecting)
            {
                Transaq_Disconnect();
            }
            else
            {
                if (!BConnecting) Transaq_Connect();
            }
        }

        private void BtnMenuItemDisconnect(object sender, RoutedEventArgs e)
        {
            Disconnect();
        }



    }

    public class HistoryItems
    {
        private int _timeframe;
        private string _seccode;

        public int TimeFrame { get; set; }
        public string Seccode { get; set; }
    }
}